package com.soul.net.http;

import com.soul.net.Request;
import com.soul.net.Response;
import com.soul.net.Service;
import org.apache.http.*;
import org.apache.http.client.methods.*;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Map;

/**
 * 发送http请求
 */
public class HttpService implements Service {
    
    public HttpResponse sendRequest(HttpRequest request) {
        CloseableHttpClient httpClient = request.getHttpClient();
        HttpUriRequest uriRequest = requestBase(request);
        try {
            CloseableHttpResponse response = httpClient.execute(uriRequest);
            return createResponse(response);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private HttpResponse createResponse(CloseableHttpResponse response) throws IOException {
        HttpResponse httpResponse = new HttpResponse();
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == HttpStatus.SC_OK) {
            httpResponse.setStatusCode(statusCode);
            for (Header allHeader : response.getAllHeaders()) {
                httpResponse.putHeader(allHeader.getName(),allHeader.getValue());
            }
            HttpEntity entity = response.getEntity();
            if (entity.isStreaming()){
                httpResponse.setStream(true);
                httpResponse.setBytes(EntityUtils.toByteArray(entity));
            }else {
                httpResponse.setContent(EntityUtils.toString(entity));
            }
        }
        return httpResponse;
    }

    @Override
    public Response sendRequest(Request request) {
        return sendRequest(request);
    }
    
    public HttpUriRequest requestBase(HttpRequest request){
        RequestBuilder builder = RequestBuilder.create(request.getMethod().name());
        if (request.getHeaders() != null){
            for (Map.Entry<String, String> entry : request.getHeaders().entrySet()) {
                builder.addHeader(entry.getKey(),entry.getValue());
            }
        }
        if (request.getQueryParams() != null){
            for (Map.Entry<String, String> entry : request.getQueryParams().entrySet()) {
                builder.addParameter(entry.getKey(),entry.getValue());
            }
        }
        if (request.getEncoding() != null){
            builder.setCharset(Charset.forName(request.getEncoding()));
        }
        builder.setUri(request.getUrl());
        if (request.getHttpContent() != null) {
            HttpEntity entity = new ByteArrayEntity(request.getHttpContent());
            builder.setEntity(entity);
        }
        return builder.build();
    }
}
